package com.zeyuan.rpcclient.netty.pro.ProtocolDesign;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.nio.charset.StandardCharsets;

public class TestHttp {
    public static void main(String[] args) {
        //通过浏览器发送8080 http请求，这里进行拦截
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.channel(NioServerSocketChannel.class);
        serverBootstrap.group(boss,worker);
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                ch.pipeline().addLast(new HttpServerCodec()); //含有http请求接码和响应编码，codec包含编码和解码
                //对上面http请求解码后还需要对解码内容进行处理，所以这里用inbound进行处理
//                ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
//
//                    @Override
//                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//                        //这里显示前面codec将http请求解码成defaulthttprequest请求路径和lasthttpcontent请求体两部分
//                        System.out.println("解码类型："+msg.getClass());
//                        if (msg instanceof HttpRequest){ //请求行，请求头
//
//                        }else if (msg instanceof HttpContent){ //请求体
//
//                        }
//                        super.channelRead(ctx, msg);
//                    }
//                });
                ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() { //SimpleChannelInboundHandler只处理特定类型的消息，只有是httprequest类型的消息才会在读取的时候进行处理
                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
                        System.out.println(msg.uri());
                        System.out.println(msg.headers());

                        //接收到http请求后要返回响应，这里响应式交给上面codec这个出站响应处理器将数据编码成bytebuf
                        DefaultFullHttpResponse resp=new DefaultFullHttpResponse(msg.protocolVersion(), HttpResponseStatus.OK);
                        byte[] bytes = "<h1>HELLO world!</h1>".getBytes(StandardCharsets.UTF_8);
                        //如果不设置content-length，浏览器不知道什么时候结束会一直转圈圈
                        resp.headers().setInt("content-length",bytes.length);
                        resp.content().writeBytes(bytes);
                        //写回响应
                        ctx.writeAndFlush(resp); //这个resp会经过上面添加的codec出站编码器返回给目标
                    }
                });
            }
        });
        try {
            ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }

    }
}
